---------------------------------------------
---------------Module Network----------------
---------------------------------------------
module(..., package.seeall)
local json = require "json"
local socket = require "socket"
local funCommon = require "common"

-----------------Properties-------------------
client = socket:tcp()
event = {}

--------------Xac thuc ung dung---------------
function connect(onConnected)
	client:connect(_G.session.ipServer,_G.session.portServer)
	client:settimeout(0)	
	Runtime:addEventListener( "enterFrame" ,function()  
												local str,err,null = client:receive("*l")
												if str~=nil and #str > 0 then
													local methodName,dataIn = getObject(str)
													if dataIn ~= nil then
														print (str)
														event[methodName](dataIn);
													end
													str = nil 
												end
											end )	
	--Khi ket noi toi server, trong 5s ma ko bat tay xac thuc xong thi server se dong ket noi
	client:send(_G.session.secretKey.."\n")
	event["9ed1b32a0babd582093e484c1a14a668"] = function(sessionId)
													_G.session.sessionId = sessionId
													print("Connect Success")
													if (onConnected and type(onConnected) == "function" ) then
														onConnected()
													end
												end	
end

-----------------CallService_------------------
function call(methodName, dataIn, onCallBack)
	print ("[libNetwork]: call - "..methodName)	
	
	-- Check Input	
	if (not methodName and type(methodName) ~= "string") then
		print ("[libNetwork]: error - "..methodName.."is not string")
		return false
	end	
	if (not dataIn and type(dataIn) ~= "table") then
		print ("[libNetwork]: error - "..dataIn.."is not table")
		return false
	end	
	
	-- Stamp Message
	local strIn = methodName .. "$"
	strIn = strIn .. json.encode(dataIn)	
	
	local crypto = require("crypto")
	local hmac = crypto.hmac(crypto.sha256,strIn,_G.session.sessionId) 
	
	strIn = strIn .. "$" .. hmac-- .. "\n"
	
	local strInXor = funCommon.xorString(strIn,_G.session.secretKey)
	
	-- Setup Event for CallBack
	if (onCallBack and type(onCallBack) == "function" ) then
		event[methodName] = onCallBack
	end
	
	-- Send to Sever
	client:send(strInXor.."\n")
	
	print ("[libNetwork]: call - "..methodName.." Sussess");
	return true
end

-----------------GetOBJ---------------------
function getObject(strIn)
	
	-- Integrity Check 
	if #strIn<65 then
		return nil,nil
	end
	if (strIn:sub(1,32) == "9ed1b32a0babd582093e484c1a14a668") then
		local j1 = string.find(strIn,"%$")	
		local j2 = string.find(strIn,"%$",j1+1)
		return strIn:sub(1,j1-1),strIn:sub(j1+1,j2-1)
	end
	
	local strInXor = strIn--funCommon.xorString(strIn,_G.session.secretKey)
	
	local i1 = string.find(strInXor,"%$")	
	local i2 = string.find(strInXor,"%$",i1+1)
	local methodName = strInXor:sub(1,i1-1)
	local jsonStr = strInXor:sub(i1+1,i2-1)
	
	hmac = crypto.hmac(crypto.sha256,methodName .. "$" .. jsonStr,_G.session.sessionId)
	if strInXor:sub(i2+1,#strInXor) ~= hmac then -- chu y ki tu CR
		return nil,nil
	end
	-- Json 
	local dataOut = {}
	dataOut = json.decode(jsonStr)
	
	if (dataOut==nil) then
		return nil,nil
	end
	-- Sussess !
	print (methodName,dataOut)
	return methodName,dataOut
end
